package com.xhx.aysnc.completablefuture;

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.springframework.scheduling.concurrent.CustomizableThreadFactory;

import lombok.extern.slf4j.Slf4j;

/**
 * 同时执行多个异步任务
 * 
 * @author xhx
 */
@Slf4j
public class ConcurrentExecutionTest {
	private static final Executor EXECUTOR = new ThreadPoolExecutor(10, 10, 60, TimeUnit.SECONDS,
			new LinkedBlockingQueue<>(200), new CustomizableThreadFactory("async-"),
			new ThreadPoolExecutor.CallerRunsPolicy());

	public static void main(String[] args) {
		log.info("start");
		CompletableFuture<List<String>> listFuture = CompletableFuture.supplyAsync(() -> getList(), EXECUTOR);
		CompletableFuture<Integer> numberFuture = CompletableFuture.supplyAsync(() -> getNumber(), EXECUTOR);
		CompletableFuture<Void> allFuture = CompletableFuture.allOf(listFuture, numberFuture);
		try {
			allFuture.get();
			log.info("number:{}", numberFuture.get());
			log.info("list:{}", listFuture.get());
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		} finally {
			allFuture.cancel(true);
			listFuture.cancel(true);
			numberFuture.cancel(true);
		}
		log.info("end");
	}

	private static Integer getNumber() {
		log.info("开始获取数字");
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			log.error(e.getMessage(), e);
		}
		int i = new Random().nextInt();
		log.info("结束获取数字-{}", i);
		return i;
	}

	private static List<String> getList() {
		log.info("开始获取列表");
		try {
			TimeUnit.SECONDS.sleep(2);
		} catch (InterruptedException e) {
			log.error(e.getMessage(), e);
		}
		List<String> list = Arrays.asList("1", "b", "3");
		log.info("结束获取列表-{}", list);
		return list;
	}

}
